from rest_framework import serializers
from .models import OAUser, UserStatusChoices, OADepartment
from rest_framework import exceptions

#继承了 serializers.Serializer，表示这是一个普通的序列化器。
class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField(required=True, error_messages={"required": "请输入邮箱！"})
    password = serializers.CharField(max_length=20, min_length=6)

    # 验证邮箱和密码     # validate 方法用来验证用户输入的数据。  attrs: 包含所有传入的数据（例如邮箱和密码）。
    def validate(self, attrs):
        email = attrs.get('email')
        password = attrs.get('password')

        if email and password:
            user = OAUser.objects.filter(email=email).first()
            if not user:
                raise serializers.ValidationError("请输入正确的邮箱！")
            if not user.check_password(password):
                raise serializers.ValidationError("请输入正确的密码！")
            # 判断状态    在models.py  中的   UserStatusChoices 中 获取状态
            if user.status == UserStatusChoices.UNACTIVE:
                raise serializers.ValidationError("该用户尚未激活！")
            elif user.status == UserStatusChoices.LOCKED:
                raise serializers.ValidationError("该用户已被锁定，请联系管理员！")
            # 为了节省执行SQL语句的次数，这里我们把user直接放到attrs中，方便在视图中使用
            attrs['user'] = user
        else:
            raise serializers.ValidationError('请传入邮箱和密码！')
        return attrs

#序列化嵌套
#功能：这个序列化器用于序列化和反序列化 OADepartment 模型实例。
class DepartmentSerializer(serializers.ModelSerializer):
    #
    class Meta:
        #model：指定了这个序列化器将处理的模型是 OADepartment。
        model = OADepartment
        #fields："__all__" 表示序列化器将包含模型中的所有字段。
        fields = "__all__"

#功能：这个序列化器用于序列化和反序列化 OAUser 模型实例，并包含嵌套的 DepartmentSerializer。
class UserSerializer(serializers.ModelSerializer):
    #department = DepartmentSerializer()：这行代码表明 UserSerializer 中的 department 字段使用
    # DepartmentSerializer 进行序列化和反序列化。

    #这样做的目的是：当序列化 OAUser 实例时，它不仅会序列化 OAUser 的字段，
    # 还会通过 DepartmentSerializer 序列化关联的 OADepartment 实例。这在需要嵌套数据表示时非常有用。
    department = DepartmentSerializer()
    class Meta:
        #model：指定了这个序列化器将处理的模型是 OAUser。
        model = OAUser
        # fields = "__all__"
        #exclude：('password', 'groups', 'user_permissions') 表示序列化器将排除这些字段，
        # 不会将它们包含在序列化后的输出中。这通常是出于安全和隐私的考虑，特别是 password 字段。
        exclude = ('password', 'groups', 'user_permissions') # 排除密码，用户组，用户权限字段

#修改密码的序列化器
class ResetPwdSerializer(serializers.Serializer):
    oldpwd = serializers.CharField(min_length=6, max_length=20)
    pwd1 = serializers.CharField(min_length=6, max_length=20)
    pwd2 = serializers.CharField(min_length=6, max_length=20)

    # validate 方法用来验证用户输入的数据。  attrs: 包含所有传入的数据（例如旧密码、新密码1、新密码2）。
    def validate(self, attrs): # attrs: 包含所有传入的数据（例如旧密码、新密码1、新密码2）。
        oldpwd = attrs['oldpwd']
        pwd1 = attrs['pwd1']
        pwd2 = attrs['pwd2']

        user = self.context['request'].user # 获取当前用户信息
        if not user.check_password(oldpwd): # 判断旧密码是否正确
            raise exceptions.ValidationError("旧密码错误！")

        if pwd1 != pwd2: # 判断新密码是否一致
            raise exceptions.ValidationError("两个新密码不一致！")
        return attrs # 返回验证后的数据
